package com.ccteam.fluidmusic.widget

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.TimeInterpolator
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.ViewPropertyAnimator
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.cardview.widget.CardView
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.FluidmusicBottomBarBinding
import com.google.android.material.animation.AnimationUtils
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.button.MaterialButton

/**
 *
 * @author Xiaoc
 * @since 2021/1/9
 *
 * 底部播放控制栏与底部导航栏结合的组合View
 * 内置控制其分别显示的动画
 */
class FluidMusicBottomBar @JvmOverloads constructor(context: Context,
                          attrs: AttributeSet? = null,
                          defStyleAttr: Int = 0): FrameLayout(context,attrs, defStyleAttr) {

    companion object{
        /**
         * 当前底部状态为全部显示
         */
        const val STATE_FULL: Int = 1
        /**
         * 当前底部状态为只显示PlayerBar
         */
        const val STATE_HALF: Int = 2
        /**
         * 当前底部状态为全部隐藏PlayerBar
         */
        const val STATE_NONE: Int = 3

        const val ANIMATION_DURATION_SLOW: Long = 225
        const val ANIMATION_DURATION_QUICK: Long = 150

        /**
         * 存储View的高度，不能存为局部变量，否则Activity重建后会恢复默认值 0
         */
        var bottomNavigationViewHeight:Int = 0
        var bottomBarAllHeight: Int = 0

    }

    private var currentState = STATE_FULL

    private val binding: FluidmusicBottomBarBinding = FluidmusicBottomBarBinding
        .inflate(LayoutInflater.from(context),this,true)

    private var currentAnimator: ViewPropertyAnimator? = null

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        bottomNavigationViewHeight = binding.mainBottomNav.measuredHeight
        bottomBarAllHeight = measuredHeight
    }

    /**
     * 得到底部导航栏 [BottomNavigationView] 的实例
     * @return [BottomNavigationView]实例
     */
    fun getBottomNavigationView(): BottomNavigationView = binding.mainBottomNav

    /**
     * 得到底部的音乐控制器容器
     */
    fun getPlayerBar(): CardView = binding.playingBarContainer

    /**
     * 得到底部音乐封面控件
     */
    fun getAlbumArtImageView(): ImageView = binding.ivPlayerBarAlbumArt

    /**
     * 得到正在播放媒体的标题
     */
    fun getNowPlayingMediaSubtitle(): TextView = binding.tvMusicTitleArtist

    /**
     * 得到播放暂停按钮
     */
    fun getPlayPauseButton(): MaterialButton = binding.btnPlayPause

    /**
     * 得到底部播放列表按钮
     */
    fun getPlaylistButton(): MaterialButton = binding.btnPlaylist

    /**
     * 将底部控制栏全部展示
     * 该方法会使用动画将底部的控制栏全部展示
     */
    fun performToFull(){
        slideToFull()
    }

    /**
     * 将底部控制栏展示到仅显示PlayerBar播放控制器
     * 该方法会使用动画将底部的播放控制器显示出来
     *
     * 这里如果发现因为Activity销毁导致还没有重测高度导致动画无法正常执行，则手动去获取对应高度的值
     */
    fun performToHalf(){
        if(bottomNavigationViewHeight == 0){
            bottomNavigationViewHeight = resources.getDimensionPixelSize(R.dimen.bottomNavigationViewHeight)
        }
        slideToHalf()
    }

    /**
     * 将底部控制栏全部隐藏
     * 该方法会使用动画将底部的控制栏全部隐藏
     *
     * 这里如果发现因为Activity销毁导致还没有重测高度导致动画无法正常执行，则手动去获取对应高度的值
     */
    fun performToNone(){
        if(bottomBarAllHeight == 0){
            bottomBarAllHeight = resources.getDimensionPixelSize(R.dimen.bottomBarAllHeight)
        }
        slideToNone()
    }


    private fun slideToFull(){
        // 当前状态如果与将要变化的状态相同，则不使用动画
        if(currentState == STATE_FULL){
            return
        }

        currentAnimator?.let {
            it.cancel()
            clearAnimation()
        }
        currentState = STATE_FULL
        animateTo(0, ANIMATION_DURATION_SLOW,AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR)
    }

    private fun slideToHalf(){
        if(currentState == STATE_HALF){
            return
        }

        currentAnimator?.let {
            it.cancel()
            clearAnimation()
        }
        currentState = STATE_HALF
        animateTo(bottomNavigationViewHeight, ANIMATION_DURATION_SLOW,AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR)
    }

    private fun slideToNone(){
        if(currentState == STATE_NONE){
            return
        }

        currentAnimator?.let {
            it.cancel()
            clearAnimation()
        }
        currentState = STATE_NONE
        animateTo(bottomBarAllHeight, ANIMATION_DURATION_QUICK,AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR)
    }


    /**
     * 动画调用，使用Y轴移位进行动画播放
     */
    private fun animateTo(targetY: Int, duration: Long, interpolator: TimeInterpolator){
        currentAnimator = animate()
            .translationY(targetY.toFloat())
            .setInterpolator(interpolator)
            .setDuration(duration)
            .setListener(object : AnimatorListenerAdapter(){
                override fun onAnimationEnd(animation: Animator?) {
                    currentAnimator = null
                }
            })
    }

}